package com.cst.security.authentication.filterInvocationSecurityMetadataSource;

import com.cst.security.authentication.accessDecisionManager.AccessDecisionManagerImpl;
import com.cst.security.userPart.entity.Sys_Permission;
import com.cst.security.userPart.entity.Sys_Permission_Role;
import com.cst.security.userPart.entity.Sys_Role;
import com.cst.security.userPart.service.SysPermissionRoleService;
import com.cst.security.userPart.service.SysPermissionService;
import com.cst.security.userPart.service.SysRoleService;
import com.cst.security.userPart.service.SysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.vote.AbstractAccessDecisionManager;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {

	private final static Logger logger = LoggerFactory.getLogger(MyInvocationSecurityMetadataSourceService.class);

	@Autowired
	private SysPermissionService sysPermissionService;

	@Autowired
	private SysPermissionRoleService sysPermissionRoleService;

	@Autowired
	private SysRoleService sysRoleService;

	@Autowired
	private SysUserService sysUserService;

	private HashMap<String, Collection<ConfigAttribute>> map =null;

	public void loadResourceDefine(){
		if(map == null){
			logger.info("map is init");
			map = new HashMap<>();
			List<Sys_Role> roles = sysRoleService.selectRoles();
			for(Sys_Role role : roles){
				String key = role.getName();
				List<ConfigAttribute> list = new ArrayList<ConfigAttribute>();
				List<Sys_Permission_Role> prs = sysPermissionRoleService.selectPermissionRole(role.getId());
				for(Sys_Permission_Role pr : prs){
					Sys_Permission permission = sysPermissionService.selectSysPermissionById(pr.getPermission_id());
                    String url = permission.getUrl();
					list.add(new SecurityConfig(url));
				}
				map.put(key,list);
			}
		}
	}


	// 此方法是为了判定用户请求的url 是否在权限表中，
	// 如果在权限表中，则返回给 decide 方法，用来判定用户是否有此权限。
	// 如果不在权限表中则放行。
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		if(map == null) {
			this.loadResourceDefine();
		}
		List<ConfigAttribute> authRoleList = null;
		//object 中包含用户请求的request 信息
		String url = ((FilterInvocation)object).getRequestUrl();
		Iterator<String>ite = map.keySet().iterator();
		while (ite.hasNext()) {
			String roleName = ite.next();
			Collection<ConfigAttribute> list = map.get(roleName);
			//需要权限才能进入的地址
			for(ConfigAttribute con : list){
				String auth_url = con.getAttribute();
				//该地址是必须要有权限才能进入
				if(auth_url.equals(url)){
					if(authRoleList == null){
						authRoleList = new ArrayList<ConfigAttribute>();
					}
					//配上这个地址需要的权限
					authRoleList.add(new SecurityConfig(roleName));
					logger.info(" access URL : "+auth_url+" need have role : "+roleName);
				}
			}

		}
		return authRoleList;
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {

		return null;
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}

}
